package controllers

import akka.actor.ActorSystem
import models._
import play.api.Logging
import play.api.libs.json.{JsValue, Json}
import play.api.mvc._

import java.sql.Timestamp
import java.time.LocalDateTime
import javax.inject._
import scala.concurrent.{ExecutionContext, Future}


/**
 * This controller creates an `Action` that demonstrates how to write
 * simple asynchronous code in a controller. It uses a timer to
 * asynchronously delay sending a response for 1 second.
 *
 * @param cc          standard controller components
 * @param actorSystem We need the `ActorSystem`'s `Scheduler` to
 *                    run code after a delay.
 * @param exec        We need an `ExecutionContext` to execute our
 *                    asynchronous code.  When rendering content, you should use Play's
 *                    default execution context, which is dependency injected.  If you are
 *                    using blocking operations, such as database or network access, then you should
 *                    use a different custom execution context that has a thread pool configured for
 *                    a blocking API.
 */
@Singleton
class KanbanController @Inject()(cc: ControllerComponents, actorSystem: ActorSystem,
                                 kb: KanbanRepository
                                )
                                (implicit exec: ExecutionContext, parser: BodyParsers.Default)
  extends AbstractController(cc) with Logging {
  implicit val myCustomCharset = Codec.javaSupported("gb18030")

  def kanban = Action { implicit request =>
    Ok(views.html.kanban.kb("kb"))
  }

  def kbdata = Action.async { implicit request =>
    kb.list.map {
      res =>
        val data = res.map(r=>Json.obj("id"->r.id,"shop" -> r.shop,"person" -> r.person,"date" -> r.date,"persent" -> r.persent))
        Ok( Json.toJson(data)).withHeaders(("Access-Control-Allow-Origin"-> "*"))
    }
//    Ok(jsData)
  }

  def kblist = Action { implicit request =>
    Ok(views.html.kanban.kbupdate("kb"))
  }

  def kboperation = Action.async { implicit request =>
    logger.debug(s"admin->body: ${request.body}")
    val req = request.body.asJson.getOrElse(Json.obj("op" -> ""))
    (req \ "op").as[String] match {
      case "list" => kb.list.map {
        res =>
          val data = res.map(r=>Json.obj("id"->r.id,"shop" -> r.shop,"person" -> r.person,"date" -> r.date,"persent" -> r.persent,"user"->r.user,"modify_date" -> r.modify_date.toString))
          Ok(Json.obj("code" -> 0, "message" -> "", "count" -> 0, "data" -> Json.toJson(data)))
      }
      case "add" => {
        val data = (req \ "data").as[JsValue]
        val shop = (data \ "shop").as[String]
        val person = (data \ "person").as[String]
        val date = (data \ "date").as[String]
        val persent = asString(data("persent")).toInt
        val user = request.session.get("accid").getOrElse("0").toInt
        val mdate = Timestamp.valueOf(LocalDateTime.now())
        kb.insert(
          Kanban(
            id = security.Encode.murmurHash32(shop + date).asInt(),
            shop = shop, person = person, persent = persent,
            user = user, modify_date = mdate, date = date))
          .map(r => Ok(r.toString))
      }
      case "update" =>{
        val data = (req \ "data").as[JsValue]
        val id = (data \ "id").as[Int]
        val shop = (data \ "shop").as[String]
        val person = (data \ "person").as[String]
        val date = (data \ "date").as[String]
        val persent = asString(data("persent")).toInt
        val user = request.session.get("accid").getOrElse("0").toInt
        val kanban: Kanban = Kanban( id = id,
          shop = shop, person = person, persent = persent,
          user = user, date = date)
        kb.update(kanban)
          .map(r => Ok(r.toString))

      }
      case "delete" => {
        logger.debug(s"${req.toString()}")
        kb.delete((req \ "data").as[Int]).map(r => Ok(r.toString))
      }
      case _ => Future(Ok("not find op"))
    }
  }

  def asString(v: JsValue) = v.asOpt[String].getOrElse(v.toString)

}
